package cn.hzc.fortess.core.shiro;

import cn.hzc.fortess.core.shiro.service.impl.UserAuthServiceServiceImpl;
import com.google.common.collect.Sets;
import cn.hzc.fortess.core.shiro.service.UserAuthService;
import cn.hzc.fortess.system.entity.Role;
import cn.hzc.fortess.system.entity.User;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Set;

public class ShiroAuthRealm extends AuthorizingRealm {

    /**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
            throws AuthenticationException {
        UserAuthService shiroFactory = UserAuthServiceServiceImpl.me();
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        User user = shiroFactory.getUserByLoginName(token.getUsername());
        ShiroUser shiroUser = shiroFactory.createShiroUser(user);
        if (CollectionUtils.isEmpty(shiroUser.getRoleList())) {
            throw new AuthenticationException("您暂未授权使用本系统!");
        }
        return shiroFactory.info(shiroUser, user, super.getName());
    }

    /**
     * 请求时权限认证
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        UserAuthService shiroFactory = UserAuthServiceServiceImpl.me();
        ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();
        final List<Role> roleList = shiroUser.getRoleList();


        final SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        final Set<String> permissionSet = Sets.newHashSet();
        final Set<String> roleNameSet = Sets.newHashSet();
        if (CollectionUtils.isEmpty(roleList)) {
            info.addStringPermissions(permissionSet);
            info.addRoles(roleNameSet);
            return info;
        }


        roleList.parallelStream().forEach(role -> {
            roleNameSet.add(role.getRoleName());
            List<String> permissions = shiroFactory.findPermissionsByRoleId(role.getId());
            if (CollectionUtils.isEmpty(permissions)) {
                return;
            }
            permissions.parallelStream().filter(s -> StringUtils.isNotBlank(s)).forEach(permission -> {
                //多个权限标识用","号分隔
                if (StringUtils.indexOf(permission, ShiroKit.NAMES_DELIMETER) > -1) {
                    for (String p : permission.split(ShiroKit.NAMES_DELIMETER)) {
                        if (StringUtils.isNotBlank(p)) {
                            permissionSet.add(p);
                        }
                    }
                } else {
                    permissionSet.add(permission);
                }
            });
        });


        info.addStringPermissions(permissionSet);
        info.addRoles(roleNameSet);

        return info;
    }

    /**
     * 设置认证加密方式
     */
    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher md5CredentialsMatcher = new HashedCredentialsMatcher();
        md5CredentialsMatcher.setHashAlgorithmName(ShiroKit.hashAlgorithmName);
        md5CredentialsMatcher.setHashIterations(ShiroKit.hashIterations);
        super.setCredentialsMatcher(md5CredentialsMatcher);
    }
}
